iT邦幫忙

2024 iThome 鐵人賽

DAY 16
0
Modern Web

現在就學React.js 系列 第 16

在React中 style & 幾種CSS的撰寫方式 - Day16

  • 分享至 

  • xImage
  •  

在 React 中撰寫 CSS 的幾個方式

在 React 中有很多種方式可以寫 CSS,將介紹幾種常見的 CSS 撰寫方式,包括外部引入 CSS 檔案、CSS Modules、Inline Styles、Styled Components 等方式。

1. 外部引入 CSS 檔案

最基本且常見的方式是在外部撰寫 CSS 檔案,再 React 元件中引入這些檔案。

CRA 創建的初始化 React 專案時,就會看到 App.css 檔案,它就是用外部方式引入到 App.js 中。

https://ithelp.ithome.com.tw/upload/images/20240930/201598958MDyZbWqiD.png

https://ithelp.ithome.com.tw/upload/images/20240930/20159895AskyqV4V3M.png

在這種方式中,由於我們是寫在 JSX 上,class 是 JS 的保留字無法使用,加上的 class,需要改為 className。因此,也可以透過三元運算子的方式,來做動態的新增或移除 class

<p className={isShow ? 'textTitle' : '' }>Hello World! </p>

用外部引入的方式,會出現個問題,所有引入的樣式,都是全局作用域,會造成可能的潛在問題-樣式覆蓋的問題。 我們來看下方的範例:

假設有兩個組件 Header.jsFooter.js

Header.js


import React from 'react';
import './Header.css'; 

const Header = () => {
  return (
    <header className="title">
      This is the Header
    </header>
  );
};

export default Header;

Header.css

.title {
  font-size: 24px;
  color: red;
}

Footer.js


import React from 'react';
import './Footer.css'; 

const Footer = () => {
  return (
    <footer className="title">
      This is the Footer
    </footer>
  );
};

export default Footer;

Footer.css

.title {
  font-size: 18px;
  color: blue;
}

最後出現的畫面是
https://ithelp.ithome.com.tw/upload/images/20240930/20159895D6b3fxjmWj.png

文字顏色竟然全部都變成是紅色!主要是樣式被覆蓋掉了!CSS在相同的權重下,後面會覆蓋上前面的內容,Header 和 Footer 都使用了同一個類名 title。當這些組件一起使用時,CSS 規則會相互覆蓋,可能導致 Header 和 Footer 的樣式混亂,例如 Header 顯示紅色,而不是藍色。那遇到這樣的問題,可以如何解決呢? 用 CSS Modules!

2. CSS Modules

CSS Modules 是一種解決全局作用域問題的方式。它允許我們將 CSS 限定在特定的組件內,避免樣式衝突。

CSS Modules帶來的好處是:

  • 解決了全局作用域的問題,讓樣式局部化。
  • 方便組件化開發,樣式更具可維護性。

將上述的範例檔案調整一下,把 css 檔案,前面加上module 後,再引入時加上 style

Header.module.css


.title {
  font-size: 24px;
  color: red;
}

Footer.module.css


.title {
  font-size: 18px;
  color: blue;
}

Header.js

import React from 'react';
import styles from './Header.module.css';  // 使用 CSS Modules

const Header = () => {
  return (
    <header className={styles.title}>
      This is the Header
    </header>
  );
};

export default Header;

Footer.js

import React from 'react';
import styles from './Footer.module.css';  // 使用 CSS Modules

const Footer = () => {
  return (
    <footer className={styles.title}>
      This is the Footer
    </footer>
  );
};

export default Footer;

會發現這樣做之後,樣式都變得正確了! css 檔案加上module後,會在編譯後讓 class 的名稱變得不同。因此就算取相同命名的 class ,就不用擔心會有覆蓋的問題了。

https://ithelp.ithome.com.tw/upload/images/20240930/20159895b9oLg2Qe82.png

3. Inline Styles

Inline Styles 是將樣式直接寫在 JSX 元素的 style 屬性中,以物件的形式呈現。每個 CSS 屬性都以駝峰式命名,如 backgroundColor,而不是傳統的 background-color

簡易範例:

import React from 'react';

function App() {

  const containerStyle = {
    textAlign: 'center',
    padding: '20px',
    backgroundColor: '#f0f0f0',
  };

  const titleStyle = {
    fontSize: '24px',
    color: '#333',
  };

  const linkStyle = {
    color: '#61dafb',
    textDecoration: 'none',
  };

  return (
    <div style={containerStyle}>
      <h1 style={titleStyle}>Hello, World!</h1>
      <a
        style={linkStyle}
        href="https://reactjs.org"
        target="_blank"
        rel="noopener noreferrer"
      >
        Learn React
      </a>
    </div>
  );
}

export default App;

Inline Styles 的優勢

  1. 簡單直接:將樣式與 JSX 元素綁定在一起,適合快速開發或處理局部樣式。
  2. 動態修改:由於樣式是以物件形式,可以根據狀態或參數動態改變樣式內容。

Inline Styles 的缺點

  1. 無法使用 CSS 偽類與偽元素:無法直接使用像:hover:before 等 CSS 偽類與偽元素以及media-query ****,這會限制部分互動效果以及響應式的設計。
  2. 難以重用:當需要在多個元件中使用相同的樣式時,Inline Styles 會導致樣式重複並變得冗長,這與外部 CSS 檔案相比不具備可重用性。

4. Styled Components

Styled Components 是 React 中非常流行的 CSS-in-JS 。它允許我們將 CSS 直接撰寫在 JavaScript 中,並且將樣式綁定到 React 組件上,使開發過程更加模組化和直觀。

為什麼使用 Styled Components?

  • 模組化管理樣式:每個組件的樣式是獨立的,避免全局樣式污染與衝突。
  • 支援動態樣式:能夠根據組件的屬性動態地改變樣式。
  • 增強 React 開發體驗:CSS 與 JavaScript 可以無縫整合,提供更靈活的樣式控制。

開始使用 Styled Components

安裝 Styled Components

首先,我們需要安裝 styled-components 套件。


npm install styled-components

這會將 styled-components 加入到你的專案中,準備好後我們可以在組件內開始使用它。

使用 Styled Components 定義樣式

下面是一個簡單範例,展示如何在 React 中使用 Styled Components 定義和應用樣式。


import React from 'react';
import styled from 'styled-components';

// 定義容器樣式
const Container = styled.div`
  padding: 20px;
  background-color: #f0f0f0;
`;

// 定義標題樣式
const Title = styled.h1`
  font-size: 24px;
  color: #333;
`;

// 應用樣式於 React 組件
const App = () => {
  return (
    <Container>
      <Title>Hello, World!</Title>
    </Container>
  );
};

export default App;

畫面出來後是這樣
https://ithelp.ithome.com.tw/upload/images/20240930/20159895qm5Crv8NLK.png

會發現樣式名稱,它會自動生成唯一的命名class名稱,也就不用擔心會有覆蓋的問題!

動態樣式

除了靜態樣式,Styled Components 也支援動態樣式,能根據組件屬性來改變外觀:


const Button = styled.button`
  background-color: ${props => (props.primary ? '#4CAF50' : '#f0f0f0')};
  color: ${props => (props.primary ? 'white' : 'black')};
  padding: 10px 20px;
`;

const App = () => {
  return (
    <div>
      <Button primary>Primary Button</Button>
      <Button>Default Button</Button>
    </div>
  );
};

在這個範例中,Button 組件的樣式會根據 primary 屬性的值動態改變。當 primary 為真時,按鈕會呈現綠色背景,否則會是預設的灰色背景。

Styled Components 的優點

  1. 模組化樣式管理:每個組件的樣式與其組件綁定在一起,不會污染全局樣式,從而避免樣式衝突問題。
  2. 支援動態樣式:能夠根據組件的屬性動態改變樣式,提升樣式的靈活性。
  3. 簡化樣式和邏輯的整合Styled Components 可以輕鬆與 JavaScript 變數、屬性以及邏輯結合,使開發過程更加彈性與效率。
  4. 自動生成唯一class:每個樣式都會生成唯一的class命名,確保不會出現樣式衝突。

Styled Components 的缺點

  1. 學習曲線:對於熟悉傳統 CSS 的開發者來說,這種方式需要一些學習成本。
  2. 可能影響效能:在大型專案中,動態生成樣式的過程可能會影響效能,特別是在有大量組件和頻繁狀態變化的情況下。

結論

在 React 中撰寫 CSS 的方式多樣化,每種方式都有其優點與限制,適合不同的應用場景:

  1. 外部引入 CSS 檔案:適合大多數簡單的專案,方便維護和管理樣式,但可能會面臨樣式全局覆蓋的問題。
  2. CSS Modules:避免樣式全局污染,讓每個組件的樣式保持獨立,適合中大型專案。
  3. Inline Styles:適合簡單、動態樣式應用,但缺乏 CSS 的偽類、偽元素支援,難以重複利用樣式。
  4. Styled Components:提供模組化和動態樣式支援,能有效解決樣式衝突問題,但在大型專案中可能會有效能考量。

選擇哪種 CSS 撰寫方式,應根據專案的需求和規模來決定。對於簡單專案,外部 CSS 或 Inline Styles 可能已經足夠,而在複雜專案中,CSS Modules 或 Styled Components 則能更好地解決樣式管理問題,提升開發體驗。

參考資料:

後記

本文將會同步更新到我的部落格

黃禎平 – Medium


上一篇
React 表單事件處理 - Day15
下一篇
綜合練習-TodoList 實作(上) Day17
系列文
現在就學React.js 31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言